/**
 * 给定数组，将其中的一些数变为相反数，使得数组和为0
 * 求需要变动的最少数量
 * 显然不用考虑0，令ZSum为正数之和，FSum为负数之和的绝对值
 * 则谁大考虑谁。假设ZSum大，令cha = ZSum - Fsum
 * 再假设从ZSum中移出x，从FSum中移出y，有
 * ZSum - x + y = Fsum - y + x
 * 所以有  cha + 2y = 2x
 * for y in [0:Fsum+1:2]:
 *    检查移动y的最小数量以及移动x的最少数量即可
 */
#include <bits/stdc++.h>
using namespace std;

using llt = long long;
using vi = vector<int>;

int N;
vi A;

void calc(const vi & w, vi & f){
    int maxv = f.size() - 1;
    f[0] = 0;
    for(auto i : w){
        for(int v=maxv;v>=i;--v){
            if(-1 == f[v - i]) continue;

            if(-1 == f[v] or f[v - i] + 1 < f[v]){
                f[v] = f[v - i] + 1;
            }
        }
    }
    return;
}

int check(int target, const vi & ff, const vi & fo){
    assert(fo.size() <= ff.size());
    int maxv = fo.size() - 1;
    
    int ans = -1;
    for(int i=0;i<=maxv;i+=2){
        if(-1 == fo[i/2]) continue;

        auto want = target + i;
        if(want & 1) continue;

        want >>= 1;
        if(-1 == ff[want]) continue;

        int tmp = ff[want] + fo[i/2];
        if(-1 == ans or tmp < ans) ans = tmp;
    }
    return ans;
}

int proc(){
    vi Zshu, Fshu;
    for(auto i : A){
        if(i > 0) Zshu.emplace_back(i);
        else if(i < 0) Fshu.emplace_back(-i);
    }

    int ZSum = accumulate(Zshu.begin(), Zshu.end(), 0);
    int FSum = accumulate(Fshu.begin(), Fshu.end(), 0);

    if(ZSum == FSum) return 0;


    vi ZD(ZSum + 1, -1);
    calc(Zshu, ZD);
    vi FD(FSum + 1, -1);    
    calc(Fshu, FD);

    if(ZSum > FSum){
        return check(ZSum - FSum, ZD, FD);
    }

    return check(FSum - ZSum, FD, ZD);
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("z.txt", "r", stdin);
#endif
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(0);
    int nofkase = 1;
    // cin >> nofkase;
    while(nofkase--){
        cin >> N;
        A.assign(N, {});
        for(auto & i : A) cin >> i;
        cout << proc() << endl;
    }
    return 0;
}